package com.goodcol.plugin.license;

import com.formdev.flatlaf.FlatLightLaf;
import com.toedter.calendar.JDateChooser;

import javax.crypto.Cipher;
import javax.swing.*;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;

/**
 * LicenseGeneratorGUI
 *
 * @author 单红宇
 * @date 2024-04-11 16:32:31
 */
public class LicenseGeneratorGUI extends JFrame {

    /**
     * 公钥，配对的私钥已经预置在插件中
     */
    private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1QwU9QcUL9Uq6owG0utqFdrMGt0VW7ODPEuMSCoBv3ocGKtauxq2FMcKyHm7GzQAOfdhe+hIbJImojP70Qc1mRdri5FgrsrX8AYQDWKWNpbXbVXctIt2xH3j7vSIjLB7SjEjiq0b4gd/6T09VWZ8rzztAXlFbXa3/auvwDyCKUy+vmfzoxmRMQ6t0AdOtUCusGL8P/2aqAf7dQA88s/p/03x/ll5lyOw6UEAh/4bn7Kekt0pDPPfTvWN/uBN4n2ToznePEF2nob8q/KV0/BpS0lhIuWTdx/YDrgFnX1wQkpv4lW2DWwXApCVpi6O98jehmGKf95VinskoDOgTH+/0QIDAQAB";

    /**
     * 注册码
     */
    private final JTextField regCodeField;
    /**
     * 有效期
     */
    private final JDateChooser dateChooser;
    /**
     * 授权码
     */
    private final JTextArea licenseCodeArea;

    /**
     * 入口
     *
     * @param args args
     */
    public static void main(String[] args) {
        FlatLightLaf.setup();
        SwingUtilities.invokeLater(LicenseGeneratorGUI::new);
    }

    /**
     * LicenseGeneratorGUI
     */
    public LicenseGeneratorGUI() {
        setTitle("QuickCode-Plugin License Generator");
        JPanel contentPanel = new JPanel();
        // 设置内容面板的内边距
        contentPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // 上下左右内边距均为10像素

        // 使用GridBagLayout布局管理器以便更精细地控制布局
        contentPanel.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5); // 上下左右内边距分别为0、0、10、0
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.anchor = GridBagConstraints.LINE_END; // 控件右对齐

        // 第一行：注册码
        JLabel regCodeLabel = new JLabel("注册码：", SwingConstants.RIGHT);
        regCodeField = new JTextField(20);
        gbc.gridx = 1;
        gbc.gridy = 1;
        contentPanel.add(regCodeLabel, gbc);
        gbc.gridx = 2;
        gbc.gridy = 1;
        contentPanel.add(regCodeField, gbc);

        // 第二行：日期
        JLabel dateLabel = new JLabel("有效期：", SwingConstants.RIGHT);
        dateChooser = new JDateChooser();
        gbc.gridx = 1;
        gbc.gridy = 2;
        contentPanel.add(dateLabel, gbc);
        gbc.gridx = 2;
        gbc.gridy = 2;
        contentPanel.add(dateChooser, gbc);

        // 第三行：授权码（多行文本域）
        JLabel authCodeLabel = new JLabel("授权码：", SwingConstants.RIGHT);
        licenseCodeArea = new JTextArea(10, 30);
        licenseCodeArea.setEditable(false);
        licenseCodeArea.setLineWrap(true);
        // 添加类似JTextField的边框
        licenseCodeArea.setBorder(new CompoundBorder(UIManager.getLookAndFeelDefaults().getBorder("TextField.border"),
                new EmptyBorder(2, 5, 2, 5)));

        JScrollPane scrollPane = new JScrollPane(licenseCodeArea,
                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setBorder(BorderFactory.createEmptyBorder());
        gbc.gridx = 1;
        gbc.gridy = 3;
        gbc.fill = GridBagConstraints.VERTICAL;
        authCodeLabel.setVerticalAlignment(SwingConstants.TOP);
        contentPanel.add(authCodeLabel, gbc);
        gbc.gridx = 2;
        gbc.gridy = 3;
        contentPanel.add(scrollPane, gbc);

        // 第四行：按钮
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        JButton generateButton = new JButton("生成授权码");
        JButton exitButton = new JButton("退出");

        exitButton.addActionListener(e -> System.exit(0));
        generateButton.addActionListener(this::onOk);

        buttonPanel.add(generateButton);
        buttonPanel.add(exitButton);

        gbc.gridwidth = 2; // 按钮占据两列
        gbc.anchor = GridBagConstraints.CENTER; // 按钮居中对齐
        gbc.gridx = 1;
        gbc.gridy = 4;
        contentPanel.add(buttonPanel, gbc);

        // 将内容面板设置为JFrame的内容面板
        setContentPane(contentPanel);
        // 设置窗口不可调整大小
        this.setResizable(false);
        // 显示窗口
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    /**
     * 生成授权码事件
     *
     * @param e e
     */
    private void onOk(ActionEvent e) {
        // 在这里实现生成授权码的功能，并将生成的授权码填入licenseCodeField
        String enteredRegistrationCode = regCodeField.getText();
        Date selectedDate = dateChooser.getDate();

        if (enteredRegistrationCode.isEmpty() || selectedDate == null) {
            licenseCodeArea.setText("");
        } else {
            // 假设generateLicense是一个自定义的方法来生成授权码
            String generatedLicenseCode = generateLicense(enteredRegistrationCode, selectedDate);
            licenseCodeArea.setText(generatedLicenseCode);
        }
    }

    /**
     * generateLicense
     *
     * @param regCode      注册码
     * @param selectedDate 有效期截止日期
     * @return String
     */
    private String generateLicense(String regCode, Date selectedDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(selectedDate);
        calendar.add(Calendar.DATE, 1);
        String json = "{\"expireTime\":\"" + calendar.getTime().getTime() + "\",\"createTime\":\"1710156960584\"," +
                "\"deviceId\":\"" + regCode + "\"}";
        return encrypt(json);
    }


    /**
     * encrypt
     *
     * @param plainText plainText
     * @return String
     */
    public static String encrypt(String plainText) {
        try {
            byte[] publicKeyBytes = Base64.getDecoder().decode(PUBLIC_KEY);
            // 创建密钥规格（KeySpec）对象，这里我们使用X509编码格式
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyBytes);
            // 获取KeyFactory实例
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            // 加密过程
            Cipher encryptCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
            // 通过KeySpec从字节数组中还原PublicKey对象
            encryptCipher.init(Cipher.ENCRYPT_MODE, keyFactory.generatePublic(x509KeySpec));
            byte[] plainBytes = plainText.getBytes(StandardCharsets.UTF_8);
            byte[] encryptedBytes = encryptCipher.doFinal(plainBytes);
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * createRSAKey
     *
     * @throws NoSuchAlgorithmException NoSuchAlgorithmException
     */
    public static void createRSAKey() throws NoSuchAlgorithmException {
        // 生成密钥对
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048); // 设置密钥长度
        KeyPair keyPair = keyGen.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        // 将密钥编码为字节数组
        byte[] publicKeyBytes = publicKey.getEncoded();
        byte[] privateKeyBytes = privateKey.getEncoded();

        // 使用Base64将字节数组转换为字符串
        String publicKeyString = Base64.getEncoder().encodeToString(publicKeyBytes);
        String privateKeyString = Base64.getEncoder().encodeToString(privateKeyBytes);

        System.out.println("Public Key as Base64 String: " + publicKeyString);
        System.out.println("Private Key as Base64 String: " + privateKeyString);
    }

}